package org.dreamwork.android.io;

import android.util.Log;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.util.EntityUtils;
import org.dreamwork.gson.GsonHelper;

import java.io.IOException;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * Created by seth.yang on 2016/11/25
 */
@Deprecated
public class HttpUtil {
    private static ClientConnectionManager manager;
    private static HttpParams params = new BasicHttpParams ();

    private static final String TAG = "HttpUtil";

    private static final boolean D = true;

    static {
        SchemeRegistry registry = new SchemeRegistry ();
        registry.register (new Scheme ("http", PlainSocketFactory.getSocketFactory (), 80));
        registry.register (new Scheme ("https", SSLSocketFactory.getSocketFactory (), 443));
        params = new BasicHttpParams ();
        params.setParameter (CoreConnectionPNames.CONNECTION_TIMEOUT, 30000);
        params.setParameter (CoreConnectionPNames.SO_TIMEOUT, 30000);
        HttpConnectionParams.setConnectionTimeout (params, 30000);
        HttpConnectionParams.setSoTimeout (params, 30000);
        manager = new ThreadSafeClientConnManager (params, registry);
    }

    public static void setTimeout (long connectTimeout, long socketTimeout) {
        if (connectTimeout > 0) {
            params.setParameter (CoreConnectionPNames.CONNECTION_TIMEOUT, connectTimeout);
            HttpConnectionParams.setConnectionTimeout (params, (int) connectTimeout);
        }

        if (socketTimeout > 0) {
            params.setParameter (CoreConnectionPNames.SO_TIMEOUT, socketTimeout);
            HttpConnectionParams.setSoTimeout (params, (int) socketTimeout);
        }
    }

    public static String get (String url) throws IOException {
        if (D)
            Log.v (TAG, "HTTP GET URL: " + url);
        HttpGet http = new HttpGet (url);
        HttpClient client = new DefaultHttpClient (manager, params);
        try {
            HttpResponse response = client.execute (http);
            StatusLine statusLine = response.getStatusLine ();
            if (statusLine.getStatusCode () != 200) {
                throw new IOException ("HTTP GET fail: " + statusLine.getReasonPhrase ());
            } else {
                return EntityUtils.toString (response.getEntity (), "utf-8");
            }
        } catch (IOException ex) {
            throw ex;
        } catch (Exception ex) {
            throw new RuntimeException (ex);
        } finally {
            http.abort ();
            manager.closeExpiredConnections ();
            manager.closeIdleConnections (10, TimeUnit.SECONDS);
            if (D)
                Log.d (TAG, "cleanup http client connections");
        }
    }

    public static<T> T get (String url, Type typeOfT) throws IOException {
        String ret = get (url);
        Gson g = new Gson ();
        return g.fromJson (ret, typeOfT);
    }

    public static String post (String url, String content) throws IOException {
        // 创建HttpPost对象。
        HttpPost post = new HttpPost (url);
        try {
            post.setEntity (new StringEntity (content, "utf-8"));
            // 发送POST请求
            HttpClient client = new DefaultHttpClient (manager, HttpUtil.params);
            client.getParams ().setParameter (CoreConnectionPNames.CONNECTION_TIMEOUT, 30000);
            client.getParams ().setParameter (CoreConnectionPNames.SO_TIMEOUT, 30000);
            HttpResponse httpResponse = client.execute (post);
            // 如果服务器成功地返回响应
            if (httpResponse.getStatusLine ().getStatusCode () == 200) {
                // 获取服务器响应字符串
                String result = EntityUtils.toString (httpResponse.getEntity ());
                dispose ();
                return result;
            }
            return null;
        } finally {
            post.abort ();
        }
    }

    public static String post (String url, Object content) throws IOException {
        Gson g = GsonHelper.getGson (true, true);
        return post (url, g.toJson (content));
    }

    public static String postMap (String url, Map<String, Object> form) throws IOException {
        Gson g = new GsonBuilder ().excludeFieldsWithoutExposeAnnotation ().create ();
        HttpPost post = new HttpPost (url);
        try {
            List<NameValuePair> params = new ArrayList<> (form.size ());
            for (String name : form.keySet ()) {
                Object value = form.get (name);
                String text  = CharSequence.class.isAssignableFrom (value.getClass ()) ?
                        value.toString () : g.toJson (value);
                params.add (new BasicNameValuePair (name, text));
            }
            post.setEntity (new UrlEncodedFormEntity (params, "utf-8"));
            HttpClient client = new DefaultHttpClient (manager, HttpUtil.params);
            client.getParams ().setParameter (CoreConnectionPNames.CONNECTION_TIMEOUT, 30000);
            client.getParams ().setParameter (CoreConnectionPNames.SO_TIMEOUT, 30000);
            HttpResponse httpResponse = client.execute (post);
            // 如果服务器成功地返回响应
            if (httpResponse.getStatusLine ().getStatusCode () == 200) {
                // 获取服务器响应字符串
                String result = EntityUtils.toString (httpResponse.getEntity (), "utf-8");
                dispose ();
                return result;
            }
        } finally {
            post.abort ();
        }

        return null;
    }

    public static void dispose () {
        manager.closeExpiredConnections ();
        manager.closeIdleConnections (30, TimeUnit.SECONDS);
        if (D)
            Log.d (TAG, "cleanup http client connections");
    }
}
